package com.wsy.wsyojcodesandbox.utils;

import cn.hutool.core.util.StrUtil;
import com.wsy.wsyojcodesandbox.model.ExecuteMessage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StopWatch;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 进程(控制台)执行工具类
 */
public class ProcessUtils {

    /**
     * 执行进程获取执行结果
     * @param runProcess
     * @param opName
     * @return
     */
    public static ExecuteMessage runProcess(Process runProcess, String opName) {
        ExecuteMessage executeMessage = new ExecuteMessage();
        StopWatch stopWatch = new StopWatch();
        try {
            stopWatch.start();
            int exitValue = runProcess.waitFor();
            executeMessage.setExitValue(exitValue);

            if(exitValue == 0) {
                System.out.println(opName + " success.");
                //分批获取控制台输出
                BufferedReader in = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                String compileLine;
                List<String> output = new ArrayList<>();
                while((compileLine = in.readLine()) != null) {
                    output.add(compileLine);
                }
                executeMessage.setMessage(StringUtils.join(output, "\n"));
            }else {
                System.out.println(opName + " failed, error code: " + exitValue);
                //分批获取
                BufferedReader in = new BufferedReader(new InputStreamReader(runProcess.getInputStream()));
                String compileLine;
                List<String> output = new ArrayList<>();
                while((compileLine = in.readLine()) != null) {
                    output.add(compileLine);
                }
                executeMessage.setMessage(StringUtils.join(output, "\n"));
                //获取错误输出
                BufferedReader errorReader = new BufferedReader(new InputStreamReader(runProcess.getErrorStream()));
                String compileErrorLine;
                List<String> errorOutput = new ArrayList<>();
                while((compileErrorLine = errorReader.readLine()) != null) {
                    errorOutput.add(compileErrorLine);
                }
                executeMessage.setMessage(StringUtils.join(errorOutput, "\n"));
            }
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
        } catch (Exception e) {
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());
            throw new RuntimeException(e);
        }

        return executeMessage;
    }

    public static ExecuteMessage runInteractProcess(Process runProcess, String args) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            //交互式从控制台的输入读取，不是直接从main(String[] args)读取
            //先用runProcess的输出流，把输入写进管道
            OutputStream outputStream = runProcess.getOutputStream();
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
            String[] s = args.split(" ");
            outputStreamWriter.write(StrUtil.join("\n", s) + "\n");
            outputStreamWriter.flush();

            //再用runProcess的输入流，把信息从管道读取
            InputStream inputStream = runProcess.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String compileLine;
            while((compileLine = in.readLine()) != null) {
                sb.append(compileLine);
            }
            executeMessage.setMessage(sb.toString());
            //释放资源
            outputStreamWriter.close();
            outputStream.close();
            inputStream.close();
            runProcess.destroy();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return executeMessage;
    }
}
